﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MAF.Common;

namespace MAF
{
    /// <summary>
    /// 内存Workspace，M有MAF的意思，还有Memory是意思
    /// </summary>
    public class MWorkspace : IWorkspace
    {
        /// <summary>
        /// 标识符名字
        /// </summary>
        private const string _identifierName = "Id";

        /// <summary>
        /// 存储对领域模型的更改
        /// </summary>
        private Dictionary<object, PersistObject> _changes;  // 变更列表

        /// <summary>
        /// 构造方法
        /// </summary>
        public MWorkspace()
        {
            _changes = new Dictionary<object, PersistObject>();
        }

        /// <summary>
        /// 保存新对象
        /// </summary>
        /// <param name="obj"></param>
        public void Save(object obj)
        {
            var id = ReflectHelper.GetMemberValue<object>(obj, "Id");
            _changes[id] = new PersistObject(obj, PersistStatus.Save);
        }

        /// <summary>
        /// 删除对象
        /// </summary>
        /// <param name="obj"></param>
        public void Delete(object id)
        {
            _changes[id] = new PersistObject(null, PersistStatus.Delete);
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="idValue"></param>
        /// <returns></returns>
        public T GetById<T>(object id)
        {
            // 先从改变列表里找
            if (_changes.ContainsKey(id))
            {
                var obj = _changes[id];
                return obj == null ? default(T) : (T)_changes[id].ObjectToBePersist;
            }

            // 再从数据库中找
            return MemoryDB.GetById<T>(id);
        }

        /// <summary>
        /// 持久化
        /// </summary>
        public void PersistAll()
        {
            foreach (var kvp in _changes)
            {
                switch (kvp.Value.State)
                {
                    case PersistStatus.Save:
                        MemoryDB.Save(kvp.Value.ObjectToBePersist);
                        break;
                    case PersistStatus.Delete:
                        MemoryDB.Delete(kvp.Key);
                        break;
                }
            }
            Clean();
        }

        /// <summary>
        /// 放弃修改
        /// </summary>
        public void Clean()
        {
            _changes.Clear();
        }

        /// <summary>
        /// 根据条件查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="query"></param>
        /// <returns></returns>
        public IList<T> GetByQuery<T>(IQuery query)
        {
            return MemoryDB.GetByQuery<T>(query);
        }

        #region 辅助类

        /// <summary>
        /// 持久化对象
        /// </summary>
        private class PersistObject
        {
            public PersistObject(object o, PersistStatus state)
            {
                ObjectToBePersist = o;
                State = state;
            }

            public object ObjectToBePersist;

            public PersistStatus State;
        }

        /// <summary>
        /// 持久化状态
        /// </summary>
        private enum PersistStatus
        {
            /// <summary>
            /// 保存
            /// </summary>
            Save,

            /// <summary>
            /// 删除
            /// </summary>
            Delete
        }

        #endregion
    }
}
